package edu.csu.smartpark.controller;

import com.alibaba.fastjson.JSONObject;
import edu.csu.smartpark.model.DO.EnterpriseDO;
import edu.csu.smartpark.model.DO.ParkDO;
import edu.csu.smartpark.model.DTO.BillDTO;
import edu.csu.smartpark.model.DTO.BillQueryDTO;
import edu.csu.smartpark.model.PO.BillTypeSetting;
import edu.csu.smartpark.model.PO.EnterprisePO;
import edu.csu.smartpark.model.VO.BillTypeSettingVO;
import edu.csu.smartpark.model.common.BusinessException;
import edu.csu.smartpark.model.common.MsgEntity;
import edu.csu.smartpark.service.BillService;
import edu.csu.smartpark.service.EnterpriseService;
import edu.csu.smartpark.service.ParkService;
import edu.csu.smartpark.util.Constants;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Map;

@RestController
@Slf4j
@RequestMapping("/bill")
public class BillController {
    @Autowired
    private BillService billService;
    @Autowired
    private ParkService parkService;
    @Autowired
    private EnterpriseService enterpriseService;

    @PostMapping("/add")
    @RequiresRoles(value = Constants.ParkAdministrator)
    public MsgEntity createBill(@RequestBody @Validated BillDTO billDTO) throws BusinessException {
        if (billDTO == null){
            return new MsgEntity("success", MsgEntity.SUCCESS, "params bind fail");
        }
        // 校验园区是否存在
        ParkDO parkDO = parkService.getParkInfoById(billDTO.getParkId());
        if (parkDO == null){
            return new MsgEntity("success", MsgEntity.SUCCESS, "park is not exist");
        }
        // 校验企业是否存在
        EnterpriseDO enterpriseDO = enterpriseService.getEnterpriseInfoById(billDTO.getEnterpriseId());
        if (enterpriseDO == null) {
            return new MsgEntity("success", MsgEntity.SUCCESS, "enterprise is not exist");
        }
        String res = billService.addBill(billDTO);
        if (res == null || res.equals("")){
            return new MsgEntity("success", MsgEntity.SUCCESS, "server error, create bill fail");
        }
        return new MsgEntity("success", MsgEntity.SUCCESS, res);
    }

    @GetMapping("/delete")
    @RequiresRoles(value = Constants.ParkAdministrator)
    public MsgEntity deleteBill(String billId) throws BusinessException {
        if (billId == null || billId.equals("")){
            return new MsgEntity("success", MsgEntity.SUCCESS, "billId can not be empty");
        }
        int res = billService.removeBill(billId);
        if (res < 0){
            return new MsgEntity("success", MsgEntity.SUCCESS, "bill delete fail, please try again");
        }
        return new MsgEntity("success", MsgEntity.SUCCESS,"bill delete success");
    }

    @PostMapping("/query")
    @RequiresRoles(value = Constants.ParkAdministrator)
    public MsgEntity queryBill(@RequestBody BillQueryDTO billQueryDTO) throws BusinessException {
        if (billQueryDTO == null){
            return new MsgEntity("success", MsgEntity.SUCCESS, "parameter can not be empty");
        }
        Map<String, Object> res = billService.getBillList(billQueryDTO);
        return new MsgEntity("success", MsgEntity.SUCCESS, res);
    }

    @PostMapping("/enterprise/query")
    @RequiresRoles(value = {Constants.FirstLevelOwnerManager, Constants.SecondLevelOwnerManager}, logical = Logical.OR)
    public MsgEntity queryEnterpriseBill(@RequestBody BillQueryDTO billQueryDTO) throws BusinessException {
        if (billQueryDTO == null){
            throw new BusinessException(BusinessException.PARAMETERERROR, "parameter can not be empty");
        }
        if (billQueryDTO.getEnterpriseId() == null){
            throw new BusinessException(BusinessException.PARAMETERERROR, "enterprise id can not be empty");
        }
        Map<String, Object> res = billService.getBillList(billQueryDTO);
        return new MsgEntity("success", MsgEntity.SUCCESS, res);
    }

    @PostMapping("/bill-type/add")
    @RequiresRoles(value = Constants.ParkAdministrator)
    public MsgEntity addBillType(@RequestBody JSONObject params) throws BusinessException {
        String parkId = params.getString("parkId");
        String name = params.getString("name");
        if (parkId == null || parkId.equals("")){
            return new MsgEntity("success", MsgEntity.SUCCESS, "park id can not be empty");
        }
        if (name == null || name.equals("")){
            return new MsgEntity("success", MsgEntity.SUCCESS, "bill type name can not be empty");
        }
        // 校验园区是否存在
        ParkDO parkDO = parkService.getParkInfoById(parkId);
        if (parkDO == null){
            return new MsgEntity("success", MsgEntity.SUCCESS, "park is not exist");
        }
        billService.addBillType(parkId, name);
        return new MsgEntity("success", MsgEntity.SUCCESS, "add bill type success");
    }

    @PostMapping("/bill-type/update")
    @RequiresRoles(value = Constants.ParkAdministrator)
    public MsgEntity updateBillType(@RequestBody JSONObject params) throws  BusinessException {
        String typeId = params.getString("typeId");
        String parkId = params.getString("parkId");
        String newTypeName = params.getString("newTypeName");
        if (typeId == null || typeId.equals("")){
            return new MsgEntity("success", MsgEntity.SUCCESS, "type id can not be empty");
        }
        if (parkId == null || parkId.equals("")){
            return new MsgEntity("success", MsgEntity.SUCCESS, "park id can not be empty");
        }
        if (newTypeName == null || newTypeName.equals("")){
            return new MsgEntity("success", MsgEntity.SUCCESS, "bill type new name can not be empty");
        }
        billService.editBillType(parkId,typeId,newTypeName);
        return new MsgEntity("success", MsgEntity.SUCCESS, "update bill type success");
    }

    @GetMapping("/bill-type/delete")
    @RequiresRoles(value = Constants.ParkAdministrator)
    public MsgEntity deleteBillType(String parkId, String typeId) throws BusinessException {
        if (typeId == null || typeId.equals("")){
            return new MsgEntity("success", MsgEntity.SUCCESS, "type id can not be empty");
        }
        if (parkId == null || parkId.equals("")){
            return new MsgEntity("success", MsgEntity.SUCCESS, "park id can not be empty");
        }
        billService.deleteBillType(parkId, typeId);
        return new MsgEntity("success", MsgEntity.SUCCESS, "delete bill type success");
    }

    @GetMapping("/bill-type/get")
    @RequiresRoles(value = Constants.ParkAdministrator)
    public MsgEntity getBillTypes(String parkId) throws BusinessException {
        if (parkId == null || parkId.equals("")){
            return new MsgEntity("success", MsgEntity.SUCCESS, "park id can not be empty");
        }
        BillTypeSetting billTypeSetting = billService.getBillTypes(parkId);
        BillTypeSettingVO billTypeSettingVO = new BillTypeSettingVO();
        BeanUtils.copyProperties(billTypeSetting, billTypeSettingVO);
        return new MsgEntity("success", MsgEntity.SUCCESS, billTypeSettingVO);
    }

}
